import { MiddlewareConsumer, Module, NestModule } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { ApiModule } from './api/api.module';
import { SharedModule } from './shared/shared.module';

import { WinstonModule } from 'nest-winston';
import * as winston from 'winston';
import 'winston-daily-rotate-file';
import chalk from 'chalk';
const {combine, timestamp, printf} = winston.format;

import methodOverride from './shared/middlewares/method-override';
import { RateLimitMiddleware } from './shared/middlewares/express-rate-limit';

import { EventEmitterModule } from '@nestjs/event-emitter';

@Module({
  imports: [
    EventEmitterModule.forRoot({
      wildcard:true,//启用通配符功能，允许 使用通配符来订阅事件
      delimiter:'.',//设置事件名的分割符，这是使用.使用为分割符 article.xxx   article.*
      global:true,//设置为全局模块，这意味着所有的模块都可以共享一个事件发射器的实例
    }),
    WinstonModule.forRoot({
      transports: [
        new winston.transports.Console({//写入控制台
          format: combine(
            timestamp({format: 'YYYY-MM-DD HH:MM:SS'}),//添加时间戳
            printf(({ timestamp, level, message, context }) => {//应用自定义格式
              return `${chalk.green('[Nest]')} ${chalk.yellow(process.pid)}  - ${timestamp}   ${chalk.red(level.toUpperCase())} [${chalk.blue(context)}] ${message}`;
            })
          )
        }),
        // 日志文件轮换
        new winston.transports.DailyRotateFile({
            //指定日志文件的文件名模式
            filename:"app-%DATE%.log",
            //指定文件的目录
            dirname:"./logs",
            //指定日期的格式
            datePattern:'YYYY-MM-DD',
            //指定日志的级别
            level:'info',
            //设置日志的最大的文件大小
            maxSize:'20m',//'1k',
            //设置日志文件的最大保留天数
            maxFiles:'14d',//14天后会自动删除
            zippedArchive:true,//指定是否压缩旧的日志文件
        }),
        new winston.transports.File({//写入文件
          filename: './logs/error.log',
          level: 'error', //日志的级别
        }),
      ],
    }),
    SharedModule, ApiModule ],
  controllers: [AppController],
  providers: [AppService],
})

export class AppModule implements NestModule {
  configure(consumer: MiddlewareConsumer) {
    consumer.apply(methodOverride).forRoutes('*');
    consumer.apply(RateLimitMiddleware).forRoutes('*');
  }
}